import json

from django.http import HttpResponse, JsonResponse
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination, CursorPagination
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, Serializer
from rest_framework.views import APIView

from api.models import Role, UserInfo


class UsersView(APIView):
    def get(self,request,*args,**kwargs):
        print(request.version)
        return HttpResponse("用户列表")


class ParserView(APIView):
    def post(self, request, *args, **kwargs):
        """前面django拿数据的困扰，在rest_framework中这两个解析器就解决了，意思就是：
        只要你两个解析器都用上了，写接口的时候，拿前端传的值，直接request.data就能拿到
        所有请求体的数据。但是一般交互，只会用JSONParser解析器（请求头必须是json格式）
        1、前端请求该接口
        2、获取前端带的请求体(基本都是post,post才有请求体，很少用get)
        3、根据请求带的请求头中的content-type与parser_classes中支持的请求头进行比较，谁符合就交给谁解析
        4、最后统一交到request.data中---->就是django中的request.post，但是在rest_framework
        人家通过这两个解析器给你做好了，request.data肯定能拿到值
        """
        print(request.data)
        print(request.META)
        print(request.META.get('HTTP_USER_AGENT'))
        return HttpResponse("ParserView")


# class RoleView(APIView):
#     def get(self, request, *args, **kwargs):
#         # values和values_list都是返回query_set对象，要转化为列表
#         roles = Role.objects.all().values('id','title')
#         print(roles)
#         roles = dict(roles)
#         # 通过json格式来传递，，或者省略直接用JsonResponse，显示中文用ensure_ascii=False
#         # ret = json.dumps(roles,ensure_ascii=False)
#         # return HttpResponse(ret)
#         return JsonResponse(roles,safe=False)

class RoleSerializer(ModelSerializer):
    """角色序列化类"""
    class Meta:
        model = Role
        fields = "__all__"

# class UserInfoSerializer(Serializer):
#     """用户序列化类"""
#     # 默认是根据序列字段名去数据库找，不加source就不能随便改序列字段名，但是一般还是会用和模型一样的名
#     username = serializers.CharField()
#     password = serializers.CharField()
#     # source会自动判断是否是可执行，既然你要显示枚举类的对应具体数据，这里类型要变为CharField
#     user_type = serializers.CharField(source='get_user_type_display')
#     # group是一对多，一个用户对应一个组，外键，可以直接点出来
#     group = serializers.CharField(source='group.title')
#     # 但这个roles是多对多，点不出来，点出来也是.all，只会显示object1.2.n
#     # roles = serializers.CharField(source='roles.all')
#     # SerializerMethodField就可以做到自定制返回值，解决多对多
#     roles = serializers.SerializerMethodField()
#
#     def get_roles(self,a):
#         return 123

class UserInfoSerializer(ModelSerializer):

    # 枚举剔出来定义
    user_type = serializers.CharField(source='get_user_type_display')
    # 一对多，由多找一，不想只要对象id，外键剔出来
    group = serializers.CharField(source='group.title')
    # 多对多，也剔出来，用source做不到那个力度，因为还有一层遍历。只能用自定义的函数。
    # 用SerializerMethodField类型，它会自动调用钩子函数get_xxx，跟字段对应的钩子方法
    roles = serializers.SerializerMethodField()

    # 这个users_query就是你在视图实例化(使用)这个类时，传入给instance的值
    def get_roles(self, users_query):
        return [{'id':role.id,'title':role.title} for role in users_query.roles.all()]

    class Meta:
        model = UserInfo
        fields = ['username','password','user_type','roles','group']
        # # 给某个字段增加或修改参数
        extra_kwargs = {'group':{'min_length':6}}


class UserInfoView(APIView):
    """用户视图"""
    def get(self, request, *args, **kwargs):
        users_query = UserInfo.objects.all()
        ser_users = UserInfoSerializer(instance=users_query,many=True)
        # 这个ser_users.data就是序列化后数据，是个列表，每个元素都是OrderDict对象
        # print(ser_users.data)
        ser = json.dumps(ser_users.data,ensure_ascii=False)
        return HttpResponse(ser)

class RoleView(APIView):
    """角色视图"""
    def get(self, request, *args, **kwargs):
        # 方式一：序列化queryset对象
        # roles_query = Role.objects.all()
        # ser = RoleSerializer(instance=roles_query,many=True)
        # roles = json.dumps(ser.data,ensure_ascii=False)
        # return HttpResponse(roles)

        # 方式二：序列化单个对象
        role_obj = Role.objects.all().first()
        ser = RoleSerializer(instance=role_obj,many=False)
        role = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(role)

    def post(self,request, *args, **kwargs):
        print(request.data)
        ser = RoleSerializer(data=request.data)
        # 从这儿入手找验证的钩子函数
        if ser.is_valid():
            print(ser.validated_data.get('title'))
        else:
            print(ser.errors)
        return HttpResponse('提交数据')






################分页

class MyPageNumberPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 3
    ordering = 'id'
    page_size_query_param = 'asd'
    max_page_size = None


class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        roles = Role.objects.all()
        # 创建分页对象，并获取数据
        pg = MyPageNumberPagination()
        pager_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
        # 就不对所有进行序列化
        # ser = RoleSerializer(instance=roles,many=True)
        ser = RoleSerializer(instance=pager_roles,many=True)

        # ret = json.dumps(ser.data,ensure_ascii=False)
        # return HttpResponse(ret)
        # return Response(ser.data)
        # 更详细，还会带url
        return pg.get_paginated_response(ser.data)


from rest_framework.generics import GenericAPIView
class Pager2View(GenericAPIView):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    pagination_class = MyPageNumberPagination

    def get(self, request, *args, **kwargs):
        roles = self.get_queryset()
        print(roles)
        pager_roles = self.paginate_queryset(roles)
        ser = self.get_serializer(instance=pager_roles, many=True)
        return Response(ser.data)


from rest_framework.viewsets import GenericViewSet
class Pager3View(GenericViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    pagination_class = MyPageNumberPagination

    def list(self, request, *args, **kwargs):
        roles = self.get_queryset()
        print(roles)
        pager_roles = self.paginate_queryset(roles)
        ser = self.get_serializer(instance=pager_roles, many=True)
        return Response(ser.data)



from rest_framework.mixins import ListModelMixin,CreateModelMixin
class Pager4View(ListModelMixin,CreateModelMixin,GenericViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    pagination_class = MyPageNumberPagination


from rest_framework.viewsets import ModelViewSet
# 这个ModelViewSet最强大，他帮我们实现了增删改查的功能，包括单条数据操作，我们只需指定数据
class Pager5View(ModelViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    pagination_class = MyPageNumberPagination


class LanView(APIView):

    def get(self,request,*args,**kwargs):
        self.renderer_classes
        return Response('das')